/*
 * 版权所有 (c) 2016 Zibin Zheng <znbin@qq.com>
 * 保留所有权利
 */

#ifndef _MULTI_BUTTON_H_
#define _MULTI_BUTTON_H_

#include <stdint.h>
#include <string.h>
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_gpio.h"

// 配置常量 - 可根据需要修改
#define TICKS_INTERVAL          5    // ms - 定时器中断间隔
#define DEBOUNCE_TICKS          3    // 最大7 (0 ~ 7) - 消抖滤波深度
#define SHORT_TICKS             (300 / TICKS_INTERVAL)   // 短按阈值
#define LONG_TICKS              (1000 / TICKS_INTERVAL)  // 长按阈值
#define PRESS_REPEAT_MAX_NUM    15   // 最大连击计数值

// 前置声明
typedef struct _Button Button;

// 按键回调函数类型
typedef void (*BtnCallback)(Button* btn_handle);

// 按键事件类型
typedef enum {
	BTN_PRESS_DOWN = 0,     // 按键按下
	BTN_PRESS_UP,           // 按键释放
	BTN_PRESS_REPEAT,       // 检测到连击
	BTN_SINGLE_CLICK,       // 单击完成
	BTN_DOUBLE_CLICK,       // 双击完成
	BTN_LONG_PRESS_START,   // 长按开始
	BTN_LONG_PRESS_HOLD,    // 长按保持
	BTN_EVENT_COUNT,        // 事件总数
	BTN_NONE_PRESS          // 无事件
} ButtonEvent;

// 按键状态机状态
typedef enum {
	BTN_STATE_IDLE = 0,     // 空闲状态
	BTN_STATE_PRESS,        // 按下状态
	BTN_STATE_RELEASE,      // 释放后等待超时状态
	BTN_STATE_REPEAT,       // 连击状态
	BTN_STATE_LONG_HOLD     // 长按保持状态
} ButtonState;

// 按键结构体
struct _Button {
	uint16_t ticks;                     // 计时计数器
	uint8_t  repeat : 4;                // 连击计数器 (0-15)
	uint8_t  event : 4;                 // 当前事件 (0-15)
	uint8_t  state : 3;                 // 状态机状态 (0-7)
	uint8_t  debounce_cnt : 3;          // 消抖计数器 (0-7)
	uint8_t  active_level : 1;          // 有效电平 (0 或 1)
	uint8_t  button_level : 1;          // 当前按键电平
	GPIO_TypeDef* button_port;          // 按键端口
	uint16_t button_pin;                // 按键引脚
	BtnCallback cb[BTN_EVENT_COUNT];    // 回调函数数组
	Button* next;                       // 链表中的下一个按键
};

#ifdef __cplusplus
extern "C" {
#endif

// 公共API函数
void button_init(Button* handle, GPIO_TypeDef* button_port, uint16_t button_pin, uint8_t active_level);
void button_attach(Button* handle, ButtonEvent event, BtnCallback cb);
void button_detach(Button* handle, ButtonEvent event);
ButtonEvent button_get_event(Button* handle);
int  button_start(Button* handle);
void button_stop(Button* handle);
void button_ticks(void);

// 工具函数
uint8_t button_get_repeat_count(Button* handle);
void button_reset(Button* handle);
int button_is_pressed(Button* handle);

#ifdef __cplusplus
}
#endif

#endif